#!/usr/bin/python3
import pika
import json
import os
import requests
import re
from requests.auth import HTTPBasicAuth
import xml.etree.ElementTree as ET

# 设置RabbitMQ连接参数
# rabbitmq_host = 'amqp.cicd.getdeepin.org'
# rabbitmq_port = 32672
# rabbitmq_username = 'user'
# rabbitmq_password = ''
# rabbitmq_queue = 'obs-ci'
rabbitmq_host = os.environ.get('rabbitmq_host')
rabbitmq_port = os.environ.get('rabbitmq_port')
rabbitmq_username = os.environ.get('rabbitmq_username')
rabbitmq_password = os.environ.get('rabbitmq_password')
rabbitmq_queue = os.environ.get('rabbitmq_queue')

# 创建RabbitMQ连接
credentials = pika.PlainCredentials(rabbitmq_username, rabbitmq_password)
parameters = pika.ConnectionParameters(host=rabbitmq_host, port=rabbitmq_port, credentials=credentials,
                heartbeat=0, connection_attempts=3, socket_timeout=300)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()

obs_host = os.environ.get('OBSHOST')
obs_username = os.environ.get('OSCUSER')
obs_password = os.environ.get('OSCPASS')
github_integration_repo = os.environ.get('GITHUB_INTEGRATION_REPO', "peeweep-test/Repository-Integration")
github_token = os.environ.get('GITHUB_TOKEN')

# 修改这里的参数值，使其与队列的当前设置相匹配
args = {
    'durable': True  # 确保这里的值为True或False，与队列的当前设置相匹配
}

# 声明队列
channel.queue_declare(queue=rabbitmq_queue, durable=args['durable'], arguments=args)

# 定义回调函数处理消息
def callback(ch, method, properties, body):
    event = json.loads(body)
    #print("接收到OBS事件: ", event)
    if event['table'] == "events" and event['database'] == "api_production":
        sql = event['sql']
        if sql and len(sql) > 0:
            #print("event_data: ", event['data'])
            pattern = r'INSERT INTO `(?P<table_name>\w+)` \((?P<columns>.*?)\) VALUES \((?P<values>.*?)\)'
            match = re.search(pattern, sql)
            if not match:
                print(f"{sql} not match sql insert")
                return
            table_name = match.group('table_name')
            columns = match.group('columns').split(', ')
            values = match.group('values').split("', '")
            print(f"表名： {table_name}")
            print("列名：", columns)
            print("值：", values)

            event_data_type = str(values[0]).replace("'","").strip()
            if "Event::Build" not in event_data_type:
                print(f"{event_data_type} not support")
                return
            payload = '"' + str(values[1]) + '"'
            event_data_payload = json.loads(json.loads(payload))
            project = event_data_payload.get('project', '')
            package = event_data_payload.get('package', '')
            repository = event_data_payload.get('repository', '')
            arch = event_data_payload.get('arch', '')
            # 同步构建状态到github commit
            if "deepin:CI" in project:
                #print(f"Handle {project}/{package} {arch} {repository} build event: {event_data_type}")
                if "PR-" in project or "topics:" in project:
                    print(f"Handle {project}/{package} {arch} build event: {event_data_type}")
                    # https://build.deepin.com/source/deepin:CI:peeweep-test:iptsd:PR-12/iptsd/_branch_request
                    url = f"{obs_host}/source/{project}/{package}/_branch_request"
                    response = requests.get(url, auth=HTTPBasicAuth(obs_username, obs_password))
                    if response.status_code == 200:
                        content = response.text
                        brinfo = json.loads(response.text)
                        # print(brinfo)
                        pull_request = brinfo.get('pull_request', '')
                        if pull_request != '':
                            head = pull_request.get('head', '')
                            if head != "":
                                sha = head.get('sha', '')
                                if sha != '':
                                    repo = head.get('repo', '')
                                    if repo != '':
                                        full_name = repo.get('full_name', '')
                                        print("Syncing build status to github")
                                        url = f"https://api.github.com/repos/{full_name}/statuses/{sha}"
                                        headers = {
                                            "Authorization": f"token {github_token}",
                                            "Content-Type": "application/vnd.github+json"
                                        }

                                        status = "success"
                                        if event_data_type == "Event::BuildFail":
                                            status = "failure"
                                        context = f"OBS: {repository}/{arch}"
                                        target_url = f"https://build.deepin.com/package/live_build_log/{project}/{package}/{repository}/{arch}"
                                        data = {
                                            "state": status,
                                            "context": context,
                                            "target_url": target_url
                                        }
                                        response = requests.post(url, headers=headers, data=json.dumps(data))

                                        if response.status_code == 201:
                                            print("Commit status uploaded successfully.")
                                        else:
                                            print("Failed to upload commit status.")
                                            print(response.text)
                                    else:
                                        print("Failed to get pull_request head's repo")
                                else:
                                    print("Failed to get pull_request head's sha")
                            else:
                                print("Failed to get pull_request's head")
                        else:
                            print("Failed to get pull_request")
                    else:
                        print("请求失败，状态码：", response.status_code)
                elif "TestingIntegration" in project:
                    print(f"Handle {project}/{package} {arch} {repository} build event: {event_data_type}")
                    pr_number = re.search(r'\d+', project).group()
                    headers = {
                        "Authorization": f"token {github_token}",
                        "Content-Type": "application/vnd.github+json"
                    }
                    url = f"https://api.github.com/repos/{github_integration_repo}/pulls/{pr_number}"
                    response = requests.get(url, headers=headers)
                    data = response.json()
                    #sha = data['head']['sha']
                    head = data.get('head', '')
                    if head != "":
                        sha = head.get('sha', '')
                        if sha != "":
                            url = f"https://api.github.com/repos/{github_integration_repo}/statuses/{sha}"
                            status = "success"
                            if event_data_type == "Event::BuildFail":
                                status = "failure"
                            context = f"{package}_{arch}_testing_repository_building"
                            target_url = f"https://build.deepin.com/package/live_build_log/{project}/{package}/{repository}/{arch}"
                            data = {
                                "state": status,
                                "context": context,
                                "target_url": target_url
                            }
                            response = requests.post(url, headers=headers, data=json.dumps(data))

                            if response.status_code == 201:
                                print("Commit status uploaded successfully.")
                            else:
                                print("Failed to upload commit status.")
                        else:
                            print("Failed to get sha with head: " + head)
                    else:
                        print(f"Failed to get {url}'s head with response {data}")
                        print(response.text)
            if "deepin:stable" in project and "Event::BuildSuccess" in event_data_type:
                url = f"{obs_host}/source/{project}/{package}/_meta"
                response = requests.get(url, auth=HTTPBasicAuth(obs_username, obs_password))
                if response.status_code == 200:
                    content = response.text
                    root = ET.fromstring(content)
                    build_tag = root.find('build')
                    new_disable = ET.Element('disable', {'arch': arch, 'repository': 'stable'})
                    build_tag.append(new_disable)
                    xml_string = ET.tostring(root, encoding="utf-8").decode("utf-8")
                    res = requests.put(url, auth=HTTPBasicAuth(obs_username, obs_password), data=xml_string)

# 开始消费队列中的消息
channel.basic_consume(queue=rabbitmq_queue, on_message_callback=callback, auto_ack=True)

print('开始监控队列，按Ctrl+C退出')
channel.start_consuming()
